require "map-dem-tings/version"
require "map-dem-tings/input_mapper"

module MapDemTings
  def self.included(base)
    base.send :extend, ClassMethods
    base.send :include, InstanceMethods
  end

  module ClassMethods

    # Example:
    #
    # define_mapping_methods(method_mapper: :mapper2,
    #                        value_mapper:  :mapper1,
    #                        inputs: %w( atlas_id )
    #                       )

    def define_mapping_methods(opts)
      method_mapper_sym = opts[:method_mapper]
      value_mapper_sym = opts[:value_mapper]
      inputs = opts[:inputs]

      method_mapper = send(method_mapper_sym)

      inputs.each do |input_name|
        define_method(method_mapper.map(input_name)) do
          send(value_mapper_sym).map(input_name)
        end
      end
    end

    def define_method_mapper(name, &block)
      iv_name = "@@#{name}"

      block_source_only = block.source.gsub("define_method_mapper(#{name.inspect})", '')

      method_source = <<-end_src
        def self.#{name}
          #{iv_name} ||= MapDemTings::InputMapper.new #{block_source_only}
        end
      end_src

      class_eval(method_source)
    end

    def define_value_mapper(name, &block)
      iv_name = "@#{name}"

      block_source_only = block.source.gsub("define_value_mapper(#{name.inspect})", '')

      method_source = <<-end_src
        def #{name}
          #{iv_name} ||= MapDemTings::InputMapper.new #{block_source_only}
        end
      end_src

      class_eval(method_source)
    end

  end

  module InstanceMethods

  end

end
